package com.doctor.utils.callback.notify;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by nieyunlong
 * 被观察者
 * on 2016/8/23.
 */
public abstract class Observable<T> {


    public final transient ArrayList<HashMap<String, T>> obserList = new ArrayList<HashMap<String, T>>();

    /* 添加观察者 包括名称及本生 */
    public void attachObserver(String obName, T ob) {
        if (obName == null || ob == null) throw new NullPointerException();
        synchronized (obserList) {
            HashMap<String, T> map = new HashMap<String, T>();
            map.put(obName, ob);
            int index = obserList.indexOf(map);
            if (index == -1) {
                obserList.add(map);
            }
        }
    }

    /* 删除观察者 */
    public void detachObserver(String obName) {
        if (obName == null) throw new NullPointerException();
        synchronized (obserList) {
            Iterator<HashMap<String, T>> iteratorMap = obserList.iterator();
            while (iteratorMap.hasNext()) {
                Iterator<Map.Entry<String, T>> iterator = iteratorMap.next().entrySet().iterator();
                while (iterator.hasNext()) {
                    if (iterator.next().getKey().equals(obName)) {
                        iteratorMap.remove();
                        break;
                    }
                }
            }
        }
    }

    /**
     * detach all observers
     */
    public void detachObservers() {
        synchronized (obserList) {
            obserList.removeAll(obserList);
        }
    }

    /**
     * Ruturn the size of observers
     */
    public int countObservers() {
        synchronized (obserList) {
            return obserList.size();
        }
    }

    /**
     * @param obserName 第一个参数为观察者名字
     * @param flag      第二个参数flag标志表示如果没有找到观察者是否通知其他所有观察者（true是false否）
     * @param objs      第三个为需要传递的参数
     */
    public abstract void notifyObserver(String obserName, boolean flag, Object... objs);
}
